#pragma once

#include "XString.h"
#include "ConfigBase.h"

namespace config {


/**
 * Configures applications to be monitored
 */
class ApplicationsConfig : public ConfigBase {
public:
	/**
	 * Selection type is used with a list of process name regexes
	 */
	enum ApplicationSelectionTypes {
		AST_ALL,
		AST_EXCEPT_FOR_SELECTED,
		AST_ONLY_SELECTED
	};

protected:
	virtual void do_save(void) const;


public:
	ApplicationsConfig(void);
	virtual ~ApplicationsConfig(void) { save(); }

	/**
	 * Given the <i>name</i> of the process, returns <i>true</i> if this
	 * process should be monitored, <i>false</i> otherwise
	 */
	bool shouldAttachToApplication(const platform::XString &name) const;

	/**
	 * Checks whether the application should be monitored, based on
	 * app list only (not considering global <i>isEnabled</i> flag
	 */
	bool isApplicationEnabled(const platform::XString &name) const;

	// direct access to settings (for configguration)
	bool isMonitoringEnabled(void) const { return m_isMonitoringEnabled; }
	ApplicationSelectionTypes getSelectionType(void) const { return m_stype; }
	const platform::XStringList & getApplicationsList(void) const { return m_listApp; }

	// updating configuration
	inline void enableMonitoring(void) { m_isMonitoringEnabled = true; changed(); }
	inline void disableMonitoring(void) { m_isMonitoringEnabled = false; changed(); }

	/** updates the type of applications selection */
	inline void setAppSelectionType(ApplicationSelectionTypes type) {
		m_stype = type;
		changed();
	}

	/** clears the list of application names regexes */
	inline void clearAppList(void) { m_listApp.clear(); changed(); }

	/** adds new regex for application name to the list */
	inline void addApplication(const platform::XString &name) { m_listApp.push_back(name); changed(); }

	/** removes single application from the list */
	inline void removeApplication(unsigned int idx) {
		changed();
		int cur = 0;
		for (platform::XStringList::iterator it = m_listApp.begin(); it != m_listApp.end(); ++it) {
			if (cur == idx) {
				m_listApp.erase(it);
				return;
			}
			cur++;
		}
	}

private:
	/** @return <i>true</i> if the <i>name</i> matches one of regexes */
	inline bool appMatchesOneOfDefined(const platform::XString &name) const;

	mutable bool						m_isSaved;

	bool								m_isMonitoringEnabled;
	ApplicationSelectionTypes			m_stype;
	platform::XStringList				m_listApp;
};


} // end namespace